/*
 * Copyright (c)  2015~2020, xforceplus
 * All rights reserved.
 * Project:datacare-orm
 * Id: StringKit.java   2020-09-29 19-20-48
 * Author: Evan
 */
package cn.datacare.orm.util.kit;

import cn.datacare.orm.util.StringUtils;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import java.util.Map;

import static cn.datacare.orm.constant.Constants.UNDERLINE;

/**
 * <p>
 * Title:
 * </p>
 * <p>
 * Description:
 * </p>
 * <p>
 * Copyright: 2015~2020
 * </p>
 * <p>
 * Company/Department: xforceplus
 * </p>
 *
 * @author Evan
 * <b>Creation Time:</b> 2020-09-29 19-20-48
 * @since V1.0
 */
public class StringKit {
    public static final String EMPTY = StringUtils.EMPTY;

    public static final int INDEX_NOT_FOUND = -1;

    public static final String[] EMPTY_STRING_ARRAY = new String[0];


    /***
     * 首字母转小写
     * @param str
     * @return String
     */
    public static String unCapitalize(String str) {
        return StringUtils.unCapitalize(str);
    }

    /**
     * 首字母转大写
     *
     * @param str
     * @return
     */
    public static String capitalize(String str) {
        return StringUtils.capitalize(str);
    }

    /**
     * 大写字母前面加上下划线并转为全小写
     *
     * @param str 字符串
     * @return
     */
    public static String enCodeUnderlined(String str) {
        char[] chars = unCapitalize(str).toCharArray();
        StringBuilder temp = new StringBuilder();
        for (int i = 0; i < chars.length; i++) {
            if (Character.isUpperCase(chars[i])) {
                temp.append(UNDERLINE);
            }
            temp.append(Character.toLowerCase(chars[i]));
        }
        return temp.toString();
    }

    /***
     * 删除下划线并转把后一个字母转成大写
     * @param str
     * @return String
     */
    public static String deCodeUnderlined(String str) {
        String[] splitArr = str.split(UNDERLINE);
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < splitArr.length; i++) {
            if (i == 0) {
                sb.append(splitArr[0].toLowerCase());
                continue;
            }

            sb.append(capitalize(splitArr[i].toLowerCase()));
        }

        return sb.toString();
    }


    /**
     * 去空格所有空格
     * @param str 去客户
     * @return
     */
    public static String trimAllWhitespace(String str) {
        if (StringUtils.isEmpty(str)) {
            return str;
        }
        return str.replace(StringUtils.SPACE, StringUtils.EMPTY);
    }

    public static String substringBeforeLast(String str, String separator) {
        if (isEmpty(str) || isEmpty(separator)) {
            return str;
        }
        int pos = str.lastIndexOf(separator);
        if (pos == INDEX_NOT_FOUND) {
            return str;
        }
        return str.substring(0, pos);
    }

    public static boolean isNotBlank(String str) {
        return !isBlank(str);
    }

    public static boolean isBlank(String str) {
        int strLen;
        if (str == null || (strLen = str.length()) == 0) {
            return true;
        }
        for (int i = 0; i < strLen; i++) {
            if ((Character.isWhitespace(str.charAt(i)) == false)) {
                return false;
            }
        }
        return true;
    }

    public static boolean endsWith(String str, String suffix, boolean ignoreCase) {
        if (str == null || suffix == null) {
            return (str == null && suffix == null);
        }
        if (suffix.length() > str.length()) {
            return false;
        }
        int strOffset = str.length() - suffix.length();
        return str.regionMatches(ignoreCase, strOffset, suffix, 0, suffix.length());
    }

    public static boolean startsWith(String str, String prefix, boolean ignoreCase) {
        if (str == null || prefix == null) {
            return (str == null && prefix == null);
        }
        if (prefix.length() > str.length()) {
            return false;
        }
        return str.regionMatches(ignoreCase, 0, prefix, 0, prefix.length());
    }


    public static String substringAfter(String str, String separator) {
        if (isEmpty(str)) {
            return str;
        }
        if (separator == null) {
            return EMPTY;
        }
        int pos = str.indexOf(separator);
        if (pos == INDEX_NOT_FOUND) {
            return EMPTY;
        }
        return str.substring(pos + separator.length());
    }


    public static boolean isBlank(final CharSequence cs) {
        int strLen;
        if (cs == null || (strLen = cs.length()) == 0) {
            return true;
        }
        for (int i = 0; i < strLen; i++) {
            if (Character.isWhitespace(cs.charAt(i)) == false) {
                return false;
            }
        }
        return true;
    }

    /**
     * 判断一个 Object 是否为空，不包含集合对象的判断
     *
     * @param obj need to determine the object
     * @return
     * @author larrykoo
     */
    public static boolean isNullOrEmpty(Object obj) {
        if (obj == null) {
            return true;
        }
        if (obj instanceof CharSequence) {
            return ((CharSequence) obj).length() == 0;
        }
        return false;
    }

    /**
     * 严格判断一个 Object 是否为空，包括对象为 null，字符串长度为0，集合类，Map 为 empty 的情况
     *
     * @param obj
     * @return
     * @author larrykoo
     */
    public static boolean isNullOrEmptyObject(Object obj) {
        if (obj == null) {
            return true;
        }
        if (obj instanceof CharSequence) {
            return ((CharSequence) obj).length() == 0;
        }

        if (obj instanceof Collection) {
            return ((Collection) obj).isEmpty();
        }
        if (obj instanceof Map) {
            return ((Map) obj).isEmpty();
        }
        if (obj instanceof Object[]) {
            Object[] object = (Object[]) obj;
            if (object.length == 0) {
                return true;
            }
        }
        return false;
    }

    public static boolean isEmpty(String str) {
        return str == null || str.length() == 0;
    }

    public static String trim(String str) {
        return str == null ? null : str.trim();
    }

    public static String[] split(String str, char separatorChar) {
        return splitWorker(str, separatorChar, false);
    }

    public static String beforeLast(String str, char separatorChar) {
        int pos = str.lastIndexOf((int) separatorChar);
        return pos == -1 ? EMPTY : str.substring(0, pos);
    }

    private static String[] splitWorker(String str, char separatorChar, boolean preserveAllTokens) {
        // Performance tuned for 2.0 (JDK1.4)
        if (str == null) {
            return null;
        }
        int len = str.length();
        if (len == 0) {
            return EMPTY_STRING_ARRAY;
        }
        List list = new ArrayList();
        int i = 0, start = 0;
        boolean match = false;
        boolean lastMatch = false;
        while (i < len) {
            if (str.charAt(i) == separatorChar) {
                if (match || preserveAllTokens) {
                    list.add(str.substring(start, i));
                    match = false;
                    lastMatch = true;
                }
                start = ++i;
                continue;
            }
            lastMatch = false;
            match = true;
            i++;
        }
        if (match || (preserveAllTokens && lastMatch)) {
            list.add(str.substring(start, i));
        }
        return (String[]) list.toArray(new String[list.size()]);
    }
}
